/**
 * 版权所有（c）2021. 上海海鼎信息工程股份有限公司，保留所有权利
 */
package com.lovely602.design.creation.abstractfactory;

import com.lovely602.design.creation.abstractfactory.demo.Animal;
import com.lovely602.design.creation.abstractfactory.demo.FarmFactory;
import com.lovely602.design.creation.abstractfactory.demo.Plant;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;

/**
 * 抽象工厂模式是一种创建型设计模式，它提供了一种将相关或相互依赖对象的创建封装在一个工厂接口的方法中，而不需要指定它们具体的类。
 * <p>
 * 抽象工厂模式是工厂方法模式的一种延伸，它在工厂方法模式的基础上提供了一种组织多个工厂方法的结构。
 * <p>
 * 在抽象工厂模式中，有两个抽象层次：抽象工厂和具体工厂。
 * <p>
 * 抽象工厂定义了一个或多个工厂方法，用于创建一组相关或依赖的产品对象。
 * <p>
 * 具体工厂实现了抽象工厂中定义的工厂方法，负责创建具体的产品对象。
 *
 * @author lizhixing
 */
public class AbstractFactoryTest {

  public static void main(String[] args) {
    try {
      FarmFactory f;
      Animal a;
      Plant p;
      f = (FarmFactory) getObject();
      a = f.newAnimal();
      p = f.newPlant();
      a.show();
      p.show();
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }

  public static Object getObject() {
    try {
      DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = dFactory.newDocumentBuilder();
      Document doc;
      InputStream is = ClassLoader.getSystemResourceAsStream("xml/abstractfactory-config.xml");
      doc = builder.parse(is);
      NodeList nl = doc.getElementsByTagName("className");
      Node classNode = nl.item(0).getFirstChild();
      String cName = classNode.getNodeValue();
      Class<?> c = Class.forName(cName);
      return c.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}
